// This file is part of OpenMeca, an easy software to do mechanical simulation.
//
// Author(s)    :  - Damien ANDRE  <openmeca@gmail.com>
//
// Copyright (C) 2012 Damien ANDRE
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


#include <QShowEvent>
#include <QMessageBox>

#include "OpenMeca/Gui/UserItemDialog.hpp"
#include "OpenMeca/Gui/MainWindow.hpp"
#include "OpenMeca/Gui/Widget.hpp"
#include "OpenMeca/Core/UserItem.hpp"
#include "OpenMeca/Core/System.hpp"

namespace OpenMeca
{
  namespace Gui
  {

   

    UserItemDialog::UserItemDialog()
      :Dialog(),
       action_(0),
       newItemMode_(false)
    {
      Ui::UserItemDialog::setupUi(this);
      QObject::connect(preview_, SIGNAL(clicked()), this, SLOT(Preview()));
      QObject::connect(cancel_ , SIGNAL(clicked()), this, SLOT(Cancel()));
      QObject::connect(ok_     , SIGNAL(clicked()), this, SLOT(Ok()));
    }

    
    UserItemDialog::~UserItemDialog()
    {
      Core::SetOf<Widget>::it it;
      for (it = widgets_.Begin() ; it != widgets_.End(); it++ )
	(*it)->ParentDeleted();
    }

    void 
    UserItemDialog::AddWidget(Widget& w)
    {
      widgets_.AddItem(w);
    }

    
    void 
    UserItemDialog::RemoveWidget(Widget& w)
    {
       widgets_.RemoveItem(w);
    }

    bool 
    UserItemDialog::Check()
    {
      Core::SetOf<Widget>::it it;
      for (it = widgets_.Begin() ; it != widgets_.End(); it++ )
	if ((*it)->Check()==false)
	  return false;
      return true;
    }

    void 
    UserItemDialog::Preview()
    {
       if (Check())
	{
	  bool ok = ApplyChangement();
	  if (!ok)
	    {
	      Cancel();
	      return;
	    }
	  Core::System::Get().Update();
	}
    }
    
    void UserItemDialog::Ok()
    {
      if (Check())
	{
	  bool ok = ApplyChangement();
	  QWidget::hide();
	  Dialog::Hide_CallBack();
	  if (ok)
	    {
	      Core::System::Get().Update();
	      Core::System::Get().GetHistoric().SystemEdited();
	    }
	  MainWindow::Get().AddToHistoric(GetAction());
	  Reset();
	}
    }
    
    void UserItemDialog::Cancel()
    {
      CancelChangement();
      QWidget::hide();
      Dialog::Hide_CallBack();
      if (IsCurrentUserItemStillExist())
	{
	  if (newItemMode_)
	    delete &GetCurrentUserItem();
	  Core::System::Get().Update();
	}
      Reset();
    }
    
    void UserItemDialog::showEvent(QShowEvent* event)
    {
      QWidget::showEvent(event);
    }

    bool
    UserItemDialog::ApplyChangement()
    {
      if (!IsCurrentUserItemStillExist())
	{
	  QMessageBox msgBox;
	  msgBox.setText(QObject::tr("The current edited item is deleted"));
	  msgBox.setWindowModality(Qt::ApplicationModal);
	  msgBox.exec();
	  return false;
	}

      Core::SetOf<Widget>::it it;
      for (it = widgets_.Begin() ; it != widgets_.End(); it++ )
	(*it)->ApplyChangement();
      return true;
      
    }

    void 
    UserItemDialog::CancelChangement()
    {
      Core::SetOf<Widget>::it it;
      for (it = widgets_.Begin() ; it != widgets_.End(); it++ )
	(*it)->CancelChangement();
    }

    void 
    UserItemDialog::Reset()
    {
      action_ = 0;
      newItemMode_ = false;
      Core::SetOf<Widget>::it it;
      for (it = widgets_.Begin() ; it != widgets_.End(); it++ )
	(*it)->Reset();
    }

    void 
    UserItemDialog::SetAction(QAction& action)
    {
      action_ = &action;
    }
    
    QAction&
    UserItemDialog::GetAction()
    {
      assert(action_ != 0);
      return *action_;
    }

    void 
    UserItemDialog::ActiveNewItemMode()
    {
      newItemMode_ = true;
    }
    
     void 
    UserItemDialog::DisableNewItemMode()
    {
      newItemMode_ = false;
    }


  }
}
